

<!DOCTYPE html>
<html lang="zh-CN" color-mode=light>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>java基础 - 唱跳rap</title>
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta name="google" content="notranslate" />
  
  <meta name="description" content="java 遗忘题目为什么说 Java 语言“编译与解释...">
  <meta name="author" content="东子">
  <link rel="icon" href="/images/icons/icon-29.png" type="image/png" sizes="16x16">
  <link rel="icon" href="/images/icons/icon-29@2x.png" type="image/png" sizes="32x32">
  <link rel="apple-touch-icon" href="/images/icons/icon-1024.png" sizes="180x180">
  <meta rel="mask-icon" href="/images/icons/stun-logo.svg" color="#333333">
  
    <meta rel="msapplication-TileImage" content="/images/icons/icon-1024.png">
    <meta rel="msapplication-TileColor" content="#000000">
  

  
<link rel="stylesheet" href="/css/style.css">


  
    
<link rel="stylesheet" href="https://at.alicdn.com/t/font_1445822_p6ry5n7lrr.css">

  

  
    
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css">

  

  
    
      
        
        
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.18.1/styles/xcode.min.css" name="highlight-style" mode="light">

      
        
        
<link rel="stylesheet" href="https://cdn.bootcss.com/highlight.js/9.18.1/styles/solarized-dark.min.css" name="highlight-style" mode="dark">

      
  

  <script>
    var CONFIG = window.CONFIG || {};
    var ZHAOO = window.ZHAOO || {};
    CONFIG = {
      isHome: false,
      fancybox: true,
      pjax: false,
      loading: {
        gif: '',
        lottie: ''
      },
      lazyload: {
        enable: true,
        only_post: 'false',
        loading: {
          gif: '',
          lottie: ''
        }
      },
      donate: {
        enable: false,
        alipay: 'https://pic.izhaoo.com/alipay.jpg',
        wechat: 'https://pic.izhaoo.com/wechat.jpg'
      },
      galleries: {
        enable: false
      },
      fab: {
        enable: true,
        always_show: false
      },
      carrier: {
        enable: true
      },
      daovoice: {
        enable: false
      },
      preview: {
        background: {
          default: '',
          api: 'https://api.paugram.com/bing/'
        },
        motto: {
          default: '我在开了灯的床头下，想问问自己的心啊。',
          typing: true,
          api: 'https://v2.jinrishici.com/one.json',
          data_contents: '["data","content"]'
        },
      },
      qrcode: {
        enable: true,
        type: 'url',
        image: 'https://pic.izhaoo.com/weapp-code.jpg',
      },
      toc: {
        enable: true
      },
      scrollbar: {
        type: 'default'
      },
      notification: {
        enable: false,
        delay: 4500,
        list: '',
        page_white_list: '',
        page_black_list: ''
      },
      search: {
        enable: false,
        path: ''
      }
    }
  </script>

  

  

<meta name="generator" content="Hexo 6.3.0"></head>

<body class="lock-screen">
  <div class="loading" id="loading"></div>
  
    


  <nav class="navbar">
    <div class="left">
      
        <i class="iconfont iconhome j-navbar-back-home"></i>
      
      
        <i class="iconfont iconqrcode j-navbar-qrcode"></i>
      
      
        <i class="iconfont iconmoono" id="color-toggle" color-toggle="light"></i>
      
      
    </div>
    <div class="center">java基础</div>
    <div class="right">
      <i class="iconfont iconmenu j-navbar-menu"></i>
    </div>
    
      <div id="qrcode-navbar"></div>
    
  </nav>

  
  

<nav class="menu">
  <div class="menu-container">
    <div class="menu-close">
      <i class="iconfont iconbaseline-close-px"></i>
    </div>
    <ul class="menu-content"><li class="menu-item">
        <a href="/ " class="underline "> 首页</a>
      </li><li class="menu-item">
        <a href="/archives/ " class="underline "> 归档</a>
      </li><li class="menu-item">
        <a href="/categories/ " class="underline "> 分类</a>
      </li><li class="menu-item">
        <a href="/about/ " class="underline "> 关于</a>
      </li></ul>
    
      <div class="menu-copyright"><p>Powered by <a target="_blank" href="https://gitee.com/comebackearly">东子</a>  | 爷-青结~~</p></div>
    
  </div>
</nav>
  <main id="main">
  <div class="article-wrap">
    <div class="row container">
      <div class="col-xl-3"></div>
      <div class="col-xl-6"><article class="article">
  <div class="wrap">
    <section class="head">
  <img   class="lazyload" data-original="https://download.logo.wine/logo/Java_(programming_language)/Java_(programming_language)-Logo.wine.png" src=""  draggable="false">
  <div class="head-mask">
    <h1 class="head-title">java基础</h1>
    <div class="head-info">
      <span class="post-info-item"><i class="iconfont iconcalendar"></i>六月 04, 2022</span>
      
      <span class="post-info-item"><i class="iconfont iconfont-size"></i>14739</span>
    </div>
  </div>
</section>
    <section class="main">
      <section class="content">
        
        <h1 id="java-遗忘题目"><a href="#java-遗忘题目" class="headerlink" title="java 遗忘题目"></a>java 遗忘题目</h1><h2 id="为什么说-Java-语言“编译与解释并存”？"><a href="#为什么说-Java-语言“编译与解释并存”？" class="headerlink" title="为什么说 Java 语言“编译与解释并存”？"></a>为什么说 Java 语言“编译与解释并存”？</h2><p>这是因为 Java 语言既具有编译型语言的特征，也具有解释型语言的特征。</p>
<p>因为 Java 程序要经过先编译，后解释两个步骤，由 Java 编写的程序需要先经过编译步骤，生成字节码（<code>.class</code> 文件），这种字节码必须由 Java 解释器来解释执行。</p>
<h2 id="基本类型和包装类型的区别"><a href="#基本类型和包装类型的区别" class="headerlink" title="基本类型和包装类型的区别"></a>基本类型和包装类型的区别</h2><ul>
<li>成员变量包装类型不赋值就是 <code>null</code> ，而基本类型有默认值且不是 <code>null</code></li>
<li>包装类型可用于泛型，而基本类型不可以。</li>
<li>基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中，基本数据类型的成员变量（未被 <code>static</code> 修饰 ）存放在 Java 虚拟机的堆中。包装类型属于对象类型，我们知道几乎所有对象实例都存在于堆中。</li>
<li>相比于对象类型， 基本数据类型占用的空间非常小。</li>
</ul>
<h2 id="包装类型的缓存机制了解么"><a href="#包装类型的缓存机制了解么" class="headerlink" title="包装类型的缓存机制了解么"></a>包装类型的缓存机制了解么</h2><p><code>Byte</code>,<code>Short</code>,<code>Integer</code>,<code>Long</code> 这 4 种包装类默认创建了数值 <strong>[-128，127]</strong> 的相应类型的缓存数据，<code>Character</code> 创建了数值在 <strong>[0,127]</strong> 范围的缓存数据，<code>Boolean</code> 直接返回 <code>True</code> or <code>False</code>。</p>
<h2 id="为什么浮点数运算的时候会有精度丢失的风险，怎么解决？"><a href="#为什么浮点数运算的时候会有精度丢失的风险，怎么解决？" class="headerlink" title="为什么浮点数运算的时候会有精度丢失的风险，怎么解决？"></a>为什么浮点数运算的时候会有精度丢失的风险，怎么解决？</h2><p><code>BigDecimal</code> 可以实现对浮点数的运算，不会造成精度丢失。</p>
<h2 id="面向对象三大特征"><a href="#面向对象三大特征" class="headerlink" title="面向对象三大特征"></a>面向对象三大特征</h2><ul>
<li>封装是指把一个对象的状态信息（也就是属性）隐藏在对象内部，不允许外部对象直接访问对象的内部信息。</li>
<li>继承 不同类型的对象，之间有共同点。每一个对象还定义了额外的特性。提高代码的重用</li>
<li>多态 表示一个对象具有多种的状态，具体表现为父类的引用指向子类的实例</li>
</ul>
<h2 id="接口和抽象类有什么区别"><a href="#接口和抽象类有什么区别" class="headerlink" title="接口和抽象类有什么区别"></a>接口和抽象类有什么区别</h2><ul>
<li>意义上：  接口用于对类的行为进行约束，你实现了某个接口就具有了对应的行为。抽象类主要用于代码复用，强调的是所属关系</li>
<li>使用上： 一个类只能继承一个类，但是可以实现多个接口</li>
<li>成员变量：接口中的成员变量只能是 <code>public static final</code> 类型的，不能被修改且必须有初始值，而抽象类的成员变量默认 default，可在子类中被重新定义，也可被重新赋值</li>
</ul>
<h2 id="深拷贝和浅拷贝区别了解吗？什么是引用拷贝？"><a href="#深拷贝和浅拷贝区别了解吗？什么是引用拷贝？" class="headerlink" title="深拷贝和浅拷贝区别了解吗？什么是引用拷贝？"></a>深拷贝和浅拷贝区别了解吗？什么是引用拷贝？</h2><ul>
<li><strong>浅拷贝</strong> 浅拷贝会在堆上创建一个新的对象，不过，如果原对象内部的属性是引用类型的话，浅拷贝会直接复制内部对象的引用地址，也就是说拷贝对象和原对象共用同一个内部对象。</li>
<li><strong>深拷贝</strong> ：深拷贝会完全复制整个对象，包括这个对象所包含的内部对象。</li>
</ul>
<h2 id="Object类的方法"><a href="#Object类的方法" class="headerlink" title="Object类的方法"></a>Object类的方法</h2><figure class="highlight processing"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">native</span> Class&lt;?&gt; <span class="title function_">getClass</span>()</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * native 方法，用于返回对象的哈希码，主要使用在哈希表中，比如 JDK 中的HashMap。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">native</span> <span class="type">int</span> <span class="title function_">hashCode</span>()</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 用于比较 2 个对象的内存地址是否相等，String 类对该方法进行了重写以用于比较字符串的值是否相等。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">equals</span>(<span class="built_in">Object</span> obj)</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * naitive 方法，用于创建并返回当前对象的一份拷贝。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">protected</span> <span class="keyword">native</span> <span class="built_in">Object</span> <span class="title function_">clone</span>() <span class="keyword">throws</span> CloneNotSupportedException</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="built_in">String</span> <span class="title function_">toString</span>()</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * native 方法，并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">native</span> <span class="keyword">void</span> <span class="title function_">notify</span>()</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * native 方法，并且不能重写。跟 notify 一样，唯一的区别就是会唤醒在此对象监视器上等待的所有线程，而不是一个线程。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">native</span> <span class="keyword">void</span> <span class="title function_">notifyAll</span>()</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * native方法，并且不能重写。暂停线程的执行。注意：sleep 方法没有释放锁，而 wait 方法释放了锁 ，timeout 是等待时间。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">native</span> <span class="keyword">void</span> <span class="title function_">wait</span>(<span class="type">long</span> timeout) <span class="keyword">throws</span> InterruptedException</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 多了 nanos 参数，这个参数表示额外时间（以毫微秒为单位，范围是 0-999999）。 所以超时的时间还需要加上 nanos 毫秒。。</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title function_">wait</span>(<span class="type">long</span> timeout, <span class="type">int</span> nanos) <span class="keyword">throws</span> InterruptedException</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 跟之前的2个wait方法一样，只不过该方法一直等待，没有超时时间这个概念</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title function_">wait</span>() <span class="keyword">throws</span> InterruptedException</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 实例被垃圾回收器回收的时候触发的操作</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title function_">finalize</span>() <span class="keyword">throws</span> Throwable &#123; &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="String、StringBuffer、StringBuilder-的区别？"><a href="#String、StringBuffer、StringBuilder-的区别？" class="headerlink" title="String、StringBuffer、StringBuilder 的区别？"></a>String、StringBuffer、StringBuilder 的区别？</h2><ul>
<li>可变性： <code>String</code> 是不可变的</li>
<li><strong>线程安全性</strong> <code>String</code> 中的对象是不可变的，也就可以理解为常量，线程安全。<code>StringBuffer</code> 对方法 <code>expandCapacity</code>、<code>append</code>、<code>insert</code>、<code>indexOf</code>了同步锁或者对调用的方法加了同步锁，所以是线程安全的。<code>StringBuilder</code> ，是线程不安全的。</li>
<li><strong>性能</strong> <code>StringBuilder</code> 相比使用 <code>StringBuffer</code> 仅能获得 10%~15% 左右的性能提升，但却要冒多线程不安全的风险</li>
</ul>
<blockquote>
<ol>
<li>操作少量的数据: 适用 <code>String</code></li>
<li>单线程操作字符串缓冲区下操作大量数据: 适用 <code>StringBuilder</code></li>
<li>多线程操作字符串缓冲区下操作大量数据: 适用 <code>StringBuffer</code></li>
</ol>
</blockquote>
<h2 id="java异常类"><a href="#java异常类" class="headerlink" title="java异常类"></a>java异常类</h2><p>上图</p>
<p><img   class="lazyload" data-original="https://gitee.com/yuan-wendong/picture-bed/raw/master/image-20230302211238445.png" src=""  alt="image-20230302211238445"></p>
<h3 id="Throwable-类常用方法有哪些"><a href="#Throwable-类常用方法有哪些" class="headerlink" title="Throwable 类常用方法有哪些"></a>Throwable 类常用方法有哪些</h3><ul>
<li><code>String getMessage()</code>: 返回异常发生时的简要描述</li>
<li><code>String toString()</code>: 返回异常发生时的详细信息</li>
<li><code>String getLocalizedMessage()</code>: 返回异常对象的本地化信息。使用 <code>Throwable</code> 的子类覆盖这个方法，可以生成本地化信息。如果子类没有覆盖该方法，则该方法返回的信息与 <code>getMessage()</code>返回的结果相同</li>
<li><code>void printStackTrace()</code>: 在控制台上打印 <code>Throwable</code> 对象封装的异常信息</li>
</ul>
<blockquote>
<p>finally块中的代码除非虚拟机坏了，不然一定会去执行。ps:👊 当在try 中写了一句return 语句，但是finally中的代码仍然会在return 之前执行。</p>
</blockquote>
<p><code>try-with-resources</code> 可以自动释放资源，这些资源一般实现了closeable接口</p>
<h3 id="try、catch、finally-考察3，请指出下面程序的运行结果"><a href="#try、catch、finally-考察3，请指出下面程序的运行结果" class="headerlink" title="try、catch、finally 考察3，请指出下面程序的运行结果"></a>try、catch、finally 考察3，请指出下面程序的运行结果</h3><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">TryDemo</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span>(<span class="params">String[] args</span>)</span> &#123;</span><br><span class="line">        System.<span class="keyword">out</span>.println(test1());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="built_in">int</span> <span class="title">test1</span>()</span> &#123;</span><br><span class="line">        <span class="built_in">int</span> i = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            i = <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">return</span> i;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            i = <span class="number">3</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>执行结果：2。</p>
<blockquote>
<p><code>finally</code> 块中的操作并不会改变已经被返回的值</p>
</blockquote>
<h2 id="什么是泛型？有什么作用"><a href="#什么是泛型？有什么作用" class="headerlink" title="什么是泛型？有什么作用"></a>什么是泛型？有什么作用</h2><p><strong>Java 泛型（Generics）</strong> 是 JDK 5 中引入的一个新特性。</p>
<p>使用泛型参数，可以增强代码的可读性以及稳定性。编译器可以对泛型参数进行检测，并且通过泛型参数可以指定传入的对象类型。如果传入其他类型的对象就会报错。</p>
<p>泛型一般有三种使用方式:<strong>泛型类</strong>、<strong>泛型接口</strong>、<strong>泛型方法</strong></p>
<h2 id="反射"><a href="#反射" class="headerlink" title="反射"></a>反射</h2><p>反射你可以获取任意一个类的所有属性和方法，你还可以调用这些方法和属性，无视限制条件</p>
<h2 id="注解"><a href="#注解" class="headerlink" title="注解"></a>注解</h2><p>可以看作是一种特殊的注释，主要用于修饰类、方法或者变量，提供某些信息供程序在编译或者运行时使用。注解本质是一个继承了 <code>Annotation</code> 的特殊接口</p>
<p>JDK 提供了很多内置的注解（比如 <code>@Override</code> 、<code>@Deprecated</code>），同时，我们还可以自定义注解。</p>
<h2 id="SPI"><a href="#SPI" class="headerlink" title="SPI"></a>SPI</h2><p>SPI 即 Service Provider Interface ，字面意思就是：“服务提供者的接口”，我的理解是：就是一个规范，给服务提供者或者扩展框架功能的开发者去使用的一个接口，类似于mysql的驱动，有很多的厂商去实现他的规范</p>
<p>一图解释：</p>
<p><img   class="lazyload" data-original="https://guide-blog-images.oss-cn-shenzhen.aliyuncs.com/github/javaguide/java/basis/spi/1ebd1df862c34880bc26b9d494535b3dtplv-k3u1fbpfcp-watermark.png" src=""  alt="img"></p>
<h2 id="序列化和反序列化"><a href="#序列化和反序列化" class="headerlink" title="序列化和反序列化"></a>序列化和反序列化</h2><blockquote>
<p>对于不想进行序列化的变量，使用 <code>transient</code> 关键字修饰。</p>
<p><code>static</code> 变量因为不属于任何对象(Object)，所以无论有没有 <code>transient</code> 关键字修饰，均不会被序列化。</p>
</blockquote>
<h3 id="常见序列化协议有哪些-为什么不推荐使用jdk自带的协议"><a href="#常见序列化协议有哪些-为什么不推荐使用jdk自带的协议" class="headerlink" title="常见序列化协议有哪些,为什么不推荐使用jdk自带的协议"></a>常见序列化协议有哪些,为什么不推荐使用jdk自带的协议</h3><p>JDK 自带的序列化方式一般不会用 ，因为序列化<strong>效率</strong>低并且存在<strong>安全问题</strong>。</p>
<ul>
<li>比较常用的序列化协议有 Hessian、Kryo、Protobuf、ProtoStuff，这些都是基于二进制的序列化协议。</li>
<li>像 JSON 和 XML 这种属于文本类序列化方式。虽然可读性比较好，但是性能较差，一般不会选择</li>
</ul>
<h2 id="String-s-x3D-new-String-“xyz”-创建了几个字符串对象？"><a href="#String-s-x3D-new-String-“xyz”-创建了几个字符串对象？" class="headerlink" title="String s &#x3D; new String(“xyz”) 创建了几个字符串对象？"></a>String s &#x3D; new String(“xyz”) 创建了几个字符串对象？</h2><p>一个或两个。如果字符串常量池已经有“xyz”，则是一个；否则，两个。</p>
<p>当字符创常量池没有 “xyz”，此时会创建如下两个对象：</p>
<p>一个是字符串字面量 “xyz” 所对应的、驻留（intern）在一个<strong>全局共享的字符串常量池</strong>中的实例，此时该<strong>实例也是在堆中，字符串常量池只放引用</strong>。</p>
<p>另一个是通过 new String() 创建并初始化的，内容与”xyz”相同的实例，也是在堆中</p>
<h2 id="Java-静态变量和成员变量的区别。"><a href="#Java-静态变量和成员变量的区别。" class="headerlink" title="Java 静态变量和成员变量的区别。"></a>Java 静态变量和成员变量的区别。</h2><p>成员变量存在于<strong>堆内存中</strong>。静态变量存在于<strong>方法区</strong>中。</p>
<p>成员变量与对象共存亡，随着对象创建而存在，随着对象被回收而释放。静态变量与类共存亡，随着类的加载而存在，随着类的消失而消失。</p>
<p>成员变量所属于对象，所以也称为实例变量。静态变量所属于类，所以也称为类变量。</p>
<p>成员变量只能被对象所调用 。静态变量可以被对象调用，也可以被类名调用。</p>
<h2 id="JDK1-8之后有哪些新特性"><a href="#JDK1-8之后有哪些新特性" class="headerlink" title="JDK1.8之后有哪些新特性"></a>JDK1.8之后有哪些新特性</h2><p><strong>接口默认方法</strong></p>
<p><strong>Lambda 表达式和函数式接口</strong></p>
<p><strong>Stream API</strong></p>
<p><strong>方法引用</strong></p>
<p><strong>日期时间API</strong></p>
<p><strong>Optional 类</strong></p>
<h2 id="零碎细小"><a href="#零碎细小" class="headerlink" title="零碎细小"></a>零碎细小</h2><h3 id="Math-round-11-5-等于多少？"><a href="#Math-round-11-5-等于多少？" class="headerlink" title="Math.round(11.5)等于多少？"></a>Math.round(11.5)等于多少？</h3><blockquote>
<p>Math.round()方法是四舍五入，原理是在原数的基础上加0.5，然后向下取整（非常重要），如果进行判断只是记住了四舍五入很多情况下是错误的</p>
</blockquote>
<h3 id="java中存2的64-2的64用什么存？"><a href="#java中存2的64-2的64用什么存？" class="headerlink" title="java中存2的64*2的64用什么存？"></a>java中存2的64*2的64用什么存？</h3><blockquote>
<p>BigInteger</p>
<p>unsigned long long类型占用8个字节（64位） 0 到 2^64 - 1。</p>
</blockquote>
<h3 id="java日期做加减法"><a href="#java日期做加减法" class="headerlink" title="java日期做加减法"></a>java日期做加减法</h3><ul>
<li>获取当前毫秒值进行加减.</li>
<li>用<strong>java</strong>.util.Calender来实现</li>
<li>使用LocalDate里面的PlusDay…方法加减</li>
</ul>
<h1 id="JUC"><a href="#JUC" class="headerlink" title="JUC"></a>JUC</h1><h2 id="wait-和-sleep-方法的区别"><a href="#wait-和-sleep-方法的区别" class="headerlink" title="wait() 和 sleep() 方法的区别"></a>wait() 和 sleep() 方法的区别</h2><p><strong>来源</strong>：来源不同：<strong>sleep() 来自 Thread 类，wait() 来自 Object 类</strong>。</p>
<p><strong>对锁</strong>：<strong>sleep 抱着锁睡，wait() 会释放同步锁</strong>，让其他线程进入 synchronized 代码块执行。</p>
<p><strong>使用范围</strong>不同：<strong>sleep() 可以在任何地方使用。wait() 只能在同步控制方法或者同步控制块</strong>里面使用，否则会抛 IllegalMonitorStateException。</p>
<p><strong>恢复方式不同</strong>：两者会暂停当前线程，但是在恢复上不太一样。sleep() 在时间到了之后会重新恢复；wait() 则需要其他线程调用同一对象的 notify()&#x2F;nofityAll() 才能重新恢复。</p>
<h2 id="线程的-sleep-方法和-yield-方法有什么区别？"><a href="#线程的-sleep-方法和-yield-方法有什么区别？" class="headerlink" title="线程的 sleep() 方法和 yield() 方法有什么区别？"></a><strong>线程的 sleep() 方法和 yield() 方法有什么区别？</strong></h2><p>线程执行 sleep() 方法后进入<strong>超时等待</strong>（TIMED_WAITING）状态，而执行 yield() 方法后进入<strong>就绪（READY）状态</strong>。</p>
<p>sleep() 方法给其他线程运行机会时<strong>不考虑线程的优先级</strong>，因此会给低优先级的线程运行的机会；<strong>yield() 方法只会给相同优先级或更高优先级的线程以运行</strong>的机会。</p>
<h2 id="HashMap-的默认初始容量是多少？HashMap-的容量有什么限制吗？"><a href="#HashMap-的默认初始容量是多少？HashMap-的容量有什么限制吗？" class="headerlink" title="HashMap 的默认初始容量是多少？HashMap 的容量有什么限制吗？"></a>HashMap 的默认初始容量是多少？HashMap 的容量有什么限制吗？</h2><p>默认初始容量是<strong>16</strong>。HashMap 的容量必须是<strong>2的N次方</strong>，HashMap 会根据我们传入的容量计算一个大于等于该容量的最小的2的N次方，<strong>例如传 9，容量为16。</strong></p>
<h2 id="HashMap-和Hashtable-的区别"><a href="#HashMap-和Hashtable-的区别" class="headerlink" title="HashMap 和Hashtable 的区别?"></a>HashMap 和Hashtable 的区别?</h2><p>HashMap 允许 key 和 value 为 null，Hashtable 不允许。</p>
<p>HashMap 的默认初始容量为 16，Hashtable 为 11。</p>
<p>HashMap 的扩容为原来的 2 倍，Hashtable 的扩容为原来的 2 倍加 1。</p>
<p>HashMap 是非线程安全的，Hashtable是线程安全的。</p>
<p>HashMap 的 hash 值重新计算过，Hashtable 直接使用 hashCode。</p>
<h2 id="Java-内存结构"><a href="#Java-内存结构" class="headerlink" title="Java 内存结构"></a>Java 内存结构</h2><p><strong>程序计数器</strong>：线程私有。一块较小的内存空间，可以看作当前线程所执行的字节码的行号指示器。<strong>如果线程正在执行的是一个Java方法，这个计数器记录的是正在执行的虚拟机字节码指令的地址；如果正在执行的是Native方法，这个计数器值则为空。</strong></p>
<p><strong>Java虚拟机栈</strong>：线程私有。它的生命周期与线程相同。<strong>虚拟机栈描述的是Java方法执行</strong>的内存模型：每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程，就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。</p>
<p><strong>本地方法栈</strong>：线程私有。本地方法栈与虚拟机栈所发挥的作用是非常相似的，它们之间的区别不过是<strong>虚拟机栈为虚拟机执行Java方法（也就是字节码）服务，而本地方法栈则为虚拟机使用到的Native方法服务。</strong></p>
<p><strong>Java堆</strong>：线程共享。对大多数应用来说，Java堆是Java虚拟机所管理的内存中最大的一块。<strong>Java堆是被所有线程共享的一块内存区域</strong>，在虚拟机启动时创建。<strong>此内存区域的唯一目的就是存放对象实例</strong>，几乎所有的对象实例都在这里分配内存。</p>
<p><strong>方法区</strong>：与Java堆一样，是各个线程共享的内存区域，它用于存储已被虚拟机加载的<strong>类信息（构造方法、接口定义）、常量、静态变量、即时编译器编译后的代码（字节码）等数据</strong>。方法区是JVM规范中定义的一个概念，具体放在哪里，不同的实现可以放在不同的地方。</p>
<p><strong>运行时常量池</strong>：运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外，还有一项信息是常量池，用于存放编译期生成的各种<strong>字面量和符号引用</strong>，这部分内容将在类加载后进入方法区的运行时常量池中存放。</p>
<h2 id="类加载的过程"><a href="#类加载的过程" class="headerlink" title="类加载的过程"></a>类加载的过程</h2><p>类加载的过程包括：<strong>加载</strong>、<strong>验证</strong>、<strong>准备</strong>、<strong>解析</strong>、<strong>初始化</strong>，其中验证、准备、解析统称为连接。</p>
<p>加载：通过一个类的全限定名来获取定义此类的二进制字节流，在内存中生成一个代表这个类的java.lang.Class对象。</p>
<p>验证：确保Class文件的字节流中包含的信息符合当前虚拟机的要求，并且不会危害虚拟机自身的安全。</p>
<p>准备：为静态变量分配内存并设置静态变量初始值，这里所说的初始值“通常情况”下是数据类型的零值。</p>
<p>解析：将常量池内的符号引用替换为直接引用。</p>
<p>初始化：到了初始化阶段，才真正开始执行类中定义的 Java 初始化程序代码。主要是<strong>静态变量赋值动作和静态语句块（static{}）中的语句</strong>。</p>
<h2 id="线程的-join-方法是干啥用的"><a href="#线程的-join-方法是干啥用的" class="headerlink" title="线程的 join() 方法是干啥用的"></a><strong>线程的 join() 方法是干啥用的</strong></h2><p>用于等待当前线程终止。如果一个线程A执行了 threadB.join() 语句，其含义是：当前<strong>线程A等待 B 线程</strong>终止之后才从 threadB.join() 返回继续往下执行自己的代码。</p>
<h2 id="编写多线程程序有几种实现方式"><a href="#编写多线程程序有几种实现方式" class="headerlink" title="编写多线程程序有几种实现方式"></a><strong>编写多线程程序有几种实现方式</strong></h2><p>1）继承 Thread 类；2）实现 Runnable 接口；3）实现 Callable 接口。</p>
<p>其中，Thread 其实也是实现了 Runable 接口。Runnable 和 Callable 的主要区别在于是否有返回值。</p>
<p>4）线程池</p>
<h2 id="Thread-调用-start-方法和调用-run-方法的区别"><a href="#Thread-调用-start-方法和调用-run-方法的区别" class="headerlink" title="Thread 调用 start() 方法和调用 run() 方法的区别"></a>Thread 调用 start() 方法和调用 run() 方法的区别</h2><p>run()：普通的方法调用，在主线程中执行，<strong>不会新建一个线程</strong>来执行。</p>
<p>start()：<strong>新启动一个线程</strong>，这时此线程处于就绪（可运行）状态，并没有运行，一旦得到 CPU 时间片，就开始执行 run() 方法。</p>
<h2 id="Java中线程几种状态"><a href="#Java中线程几种状态" class="headerlink" title="Java中线程几种状态"></a>Java中线程几种状态</h2><p><strong>NEW</strong>：新建但是尚未启动的线程处于此状态，没有调用 start() 方法。</p>
<p><strong>RUNNABLE</strong>：包含就绪（READY）和运行中（RUNNING）两种状态。线程调用 start() 方法会会进入就绪（READY）状态，等待获取 CPU 时间片。如果成功获取到 CPU 时间片，则会进入运行中（RUNNING）状态。</p>
<p><strong>BLOCKED</strong>：线程在进入同步方法&#x2F;同步块（synchronized）时被阻塞，等待同步锁的线程处于此状态。</p>
<p><strong>WAITING</strong>：无限期等待另一个线程执行特定操作的线程处于此状态，需要被显示的唤醒，否则会一直等待下去。例如对于 Object.wait()，需要等待另一个线程执行 Object.notify() 或 Object.notifyAll()；对于 Thread.join()，则需要等待指定的线程终止。</p>
<p><strong>TIMED_WAITING</strong>：在指定的时间内等待另一个线程执行某项操作的线程处于此状态。跟 WAITING 类似，区别在于该状态有超时时间参数，在超时时间到了后会自动唤醒，避免了无期限的等待。</p>
<p><strong>TERMINATED</strong>：执行完毕已经退出的线程处于此状态。</p>
<p>线程在给定的时间点只能处于一种状态。这些状态是虚拟机状态，不反映任何操作系统线程状态。</p>
<h2 id="synchronized-和-Lock-的区别"><a href="#synchronized-和-Lock-的区别" class="headerlink" title="synchronized 和 Lock 的区别"></a>synchronized 和 Lock 的区别</h2><p>1）Lock 是一个<strong>接口</strong>；synchronized 是 Java 中的关键字，synchronized 是内置的语言实现；</p>
<p>2）Lock 在<strong>发生异常</strong>时，如果没有主动通过 unLock() 去释放锁，很可能会造成死锁现象，因此使用 Lock 时需要在 finally 块中释放锁；synchronized 不需要手动获取锁和释放锁，在发生异常时，会自动释放锁，因此不会导致死锁现象发生；</p>
<p>3）<strong>Lock 的使用更加灵活</strong>，可以有响应中断、有超时时间等；而 synchronized 却不行，使用 synchronized 时，等待的线程会一直等待下去，直到获取到锁；</p>
<p>4）在性能上，随着近些年 synchronized 的不断优化，Lock 和 synchronized 在性能上已经没有很明显的差距了，所以性能不应该成为我们选择两者的主要原因。官方推荐尽量使用 synchronized，除非 synchronized 无法满足需求时，则可以使用 Lock</p>
<h2 id="线程池的参数"><a href="#线程池的参数" class="headerlink" title="线程池的参数"></a>线程池的参数</h2><p>threadFactory（线程工厂）：用于创建工作线程的工厂。</p>
<p>corePoolSize（核心线程数）：当线程池运行的线程少于 corePoolSize 时，将创建一个新线程来处理请求，即使其他工作线程处于空闲状态。</p>
<p>maximumPoolSize（最大线程数）：线程池允许开启的最大线程数。</p>
<p>keepAliveTime（保持存活时间）：如果线程池当前线程数超过 corePoolSize，则多余的线程空闲时间超过 keepAliveTime 时会被终止。</p>
<p>workQueue（队列）：用于保留任务并移交给工作线程的阻塞队列。</p>
<p>handler（拒绝策略）：往线程池添加任务时，将在下面两种情况触发拒绝策略：1）线程池运行状态不是 RUNNING；2）线程池已经达到最大线程数，并且阻塞队列已满时。</p>
<h2 id="线程池有哪些拒绝策略"><a href="#线程池有哪些拒绝策略" class="headerlink" title="线程池有哪些拒绝策略"></a>线程池有哪些拒绝策略</h2><p><strong>AbortPolicy</strong>：中止策略。默认的拒绝策略，直接抛出 RejectedExecutionException。调用者可以捕获这个异常，然后根据需求编写自己的处理代码。</p>
<p><strong>DiscardPolicy</strong>：抛弃策略。什么都不做，直接抛弃被拒绝的任务。不抛异常</p>
<p><strong>DiscardOldestPolicy</strong>：抛弃最老策略。抛弃阻塞队列中最老的任务，相当于就是队列中下一个将要被执行的任务，然后重新提交被拒绝的任务。如果阻塞队列是一个优先队列，那么“抛弃最旧的”策略将导致抛弃优先级最高的任务，因此最好不要将该策略和优先级队列放在一起使用。</p>
<p><strong>CallerRunsPolicy</strong>：调用者运行策略。在调用者线程中执行该任务。该策略实现了一种调节机制，该策略既不会抛弃任务，也不会抛出异常，而是将任务回退到调用者（调用线程池执行任务的主线程），由于执行任务需要一定时间，因此主线程至少在一段时间内不能提交任务，从而使得线程池有时间来处理完正在执行的任务。</p>
<h2 id="为什么String定义为final"><a href="#为什么String定义为final" class="headerlink" title="为什么String定义为final"></a>为什么String定义为final</h2><ol>
<li><strong>安全性</strong>：由于String对象是不可变的，它的值不能被修改，因此在<strong>多线程环境下，对String对象的读写操作是安全的</strong>，不需要额外的同步机制。</li>
<li><strong>缓存利用</strong>：由于String对象的不可变性，相同的字符串可以被缓存起来以提高性能。相同对象放在常量池中。</li>
<li><strong>效率</strong>： 看作常量编译时预处理，由于String对象是不可变的，它可以被视为一种常量，因此在编译时可以进行优化。例如，如果一个方法中多次使用相同的字符串，Java可以将其编译为一个常量，以提高程序的效率。</li>
</ol>
<h2 id="HashMap中常用的方法有哪些"><a href="#HashMap中常用的方法有哪些" class="headerlink" title="HashMap中常用的方法有哪些"></a>HashMap中常用的方法有哪些</h2><p>1、**put(K key, V value)**： 将键（key）&#x2F;值（value）映射存放到Map集合中。</p>
<p>2、**get(Object key)**： 返回指定键所映射的值，没有该key对应的值则返回 null。</p>
<p>3、size()： 返回Map集合中数据数量。</p>
<p>4、clear()： 清空Map集合。</p>
<p>5、isEmpty()： 判断Map集合中是否有数据，如果没有则返回true，否则返回false。</p>
<p>6、remove(Object key)： 删除Map集合中键为key的数据并返回其所对应value值。</p>
<p>7**、values()**： 返回Map集合中所有value组成的以Collection数据类型格式数据。</p>
<p>8、**containsKey(Object key)**： 判断集合中是否包含指定键，包含返回 true，否则返回false。</p>
<p>9、**containsValue(Object value)**： 判断集合中是否包含指定值，包含返回 true，否则返回false。</p>
<p>10、**keySet()**： 返回Map集合中所有key组成的Set集合。</p>
<p>11、**entrySet()**： 将Map集合每个key-value转换为一个Entry对象并返回由所有的Entry对象组成的Set集合</p>
<h2 id="枚举，以及枚举的底层原理"><a href="#枚举，以及枚举的底层原理" class="headerlink" title="枚举，以及枚举的底层原理"></a>枚举，以及枚举的底层原理</h2><h3 id="基本操作"><a href="#基本操作" class="headerlink" title="基本操作"></a>基本操作</h3><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">PayTypeEnum</span> &#123;</span><br><span class="line">    <span class="comment">/** 支付宝*/</span></span><br><span class="line">    <span class="built_in">ALI_PAY</span>(<span class="number">1</span>, <span class="string">&quot;ALI_PAY&quot;</span>),</span><br><span class="line">    <span class="comment">/** 微信支付*/</span></span><br><span class="line">    <span class="built_in">WECHAT_PAY</span>(<span class="number">2</span>, <span class="string">&quot;WECHAT_PAY&quot;</span>);</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> code;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">String</span> describe;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">PayTypeEnum</span>(<span class="type">int</span> code, <span class="type">String</span> describe) &#123;</span><br><span class="line">        <span class="keyword">this</span>.code = code;</span><br><span class="line">        <span class="keyword">this</span>.describe = describe;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//根据编码获取支付方式</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> PayTypeEnum <span class="title">find</span><span class="params">(<span class="type">int</span> code)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">for</span> (PayTypeEnum payTypeEnum : <span class="built_in">values</span>()) &#123;</span><br><span class="line">            <span class="keyword">if</span> (payTypeEnum.<span class="built_in">getCode</span>() == code) &#123;</span><br><span class="line">                <span class="keyword">return</span> payTypeEnum;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> null;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>本身的方法：</p>
<p><strong>valueOf()方法</strong></p>
<p>这是一个静态方法，传入一个字符串(枚举的名称)，获取枚举类。如果传入的名称不存在，则报错。</p>
<p><strong>values()方法</strong></p>
<p>返回包含枚举类中所有枚举数据的一个数组。</p>
<p><strong>ordinal()方法</strong></p>
<p>默认情况下，枚举类会给定义的枚举提供一个默认的次序，ordinal()方法就可以返回枚举的次序。</p>
<p><strong>name()、toString()方法</strong></p>
<p>返回定义枚举用的名称。</p>
<h3 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h3><p>以枚举Season为例，分析一下枚举的底层。表面上看，一个枚举很简单：</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">public enum Season &#123;</span><br><span class="line">    <span class="regexp">//</span>春</span><br><span class="line">    SPRING,</span><br><span class="line">    <span class="regexp">//</span>夏</span><br><span class="line">    SUMMER,</span><br><span class="line">    <span class="regexp">//</span>秋</span><br><span class="line">    AUTUMN,</span><br><span class="line">    <span class="regexp">//</span>冬</span><br><span class="line">    WINTER;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>javap -v&#96;对Season.class文件反编译，首先我们看到枚举是<strong>继承了抽象类Enum的类</strong>。</p>
<figure class="highlight fortran"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Season <span class="keyword">extends</span> java.lang.<span class="keyword">Enum</span>&lt;Season&gt;</span><br></pre></td></tr></table></figure>

<p>第二，通过一段静态代码块初始化枚举。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">。。。。</span><br></pre></td></tr></table></figure>

<p>这段静态代码块的作用就是<strong>生成四个静态常量字段的值</strong>，还生成了**$VALUES字段数组**，用于保存枚举类定义的枚举常量。相当于执行了以下代码：</p>
<figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Season SPRING = <span class="keyword">new</span> Season1();</span><br><span class="line">Season SUMMER = <span class="keyword">new</span> Season2();</span><br><span class="line">Season AUTUMN = <span class="keyword">new</span> Season3();</span><br><span class="line">Season WINTER = <span class="keyword">new</span> Season4();</span><br><span class="line">Season[] <span class="symbol">$VALUES</span> = <span class="keyword">new</span> Season[<span class="number">4</span>];</span><br><span class="line"><span class="symbol">$VALUES</span>[<span class="number">0</span>] = SPRING;</span><br><span class="line"><span class="symbol">$VALUES</span>[<span class="number">1</span>] = SUMMER;</span><br><span class="line"><span class="symbol">$VALUES</span>[<span class="number">2</span>] = AUTUMN;</span><br><span class="line"><span class="symbol">$VALUES</span>[<span class="number">3</span>] = WINTER;</span><br></pre></td></tr></table></figure>

<p>第三个，关于values()方法，这是一个静态方法，作用是返回该枚举类的数组，底层实现原理，其实是这样的。</p>
<figure class="highlight delphi"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> io.github.yehongzhi.user.redisLock.Season[] values();</span><br><span class="line">    Code:</span><br><span class="line">       <span class="number">0</span>: getstatic     <span class="string">#1</span>                  <span class="comment">// Field $VALUES:[Lio/github/yehongzhi/user/redisLock/Season;</span></span><br><span class="line">       <span class="number">3</span>: invokevirtual <span class="string">#2</span>                  <span class="comment">// Method &quot;[Lio/github/yehongzhi/user/redisLock/Season;&quot;.clone:()Ljava/lang/Object;</span></span><br><span class="line">       <span class="number">6</span>: checkcast     <span class="string">#3</span>                  <span class="comment">// class &quot;[Lio/github/yehongzhi/user/redisLock/Season;&quot;</span></span><br><span class="line">       <span class="number">9</span>: areturn</span><br></pre></td></tr></table></figure>

<p>其实是将静态代码块初始化的$VALUES数组克隆一份，然后强转成Season[]返回。相当于这样：</p>
<figure class="highlight scss"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">public static Season<span class="selector-attr">[]</span> <span class="built_in">values</span>()&#123;</span><br><span class="line">    return (Season[])<span class="variable">$VALUES</span><span class="selector-class">.clone</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>所以表面上，只是加了一个enum关键字定义枚举，但是底层一旦确认是枚举类，则会由编译器对枚举类进行特殊处理，通过静态代码块初始化枚举，只要是枚举就一定会提供values()方法。</p>
<p>通过反编译我们也知道所有的枚举父类都是抽象类Enum，所以Enum有的成员变量，实现的接口，子类也会有。</p>
<p>所以只要是枚举都会有<strong>name，ordinal</strong>这两个字段，并且我们看Enum的构造器。</p>
<figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">protected</span> <span class="title">Enum</span><span class="params">(<span class="type">String</span> name, <span class="type">int</span> ordinal)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.name = name;</span><br><span class="line">    <span class="keyword">this</span>.ordinal = ordinal;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>翻译一下上面那段英文，意思大概是：<strong>唯一的构造器，程序员没法调用此构造器</strong>，它是供编译器响应枚举类型声明而使用的。得出结论，枚举实例的创建也是由编译器完成的。</p>
<h3 id="枚举实现单例"><a href="#枚举实现单例" class="headerlink" title="枚举实现单例"></a>枚举实现单例</h3><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SingletonObj</span> &#123;</span><br><span class="line">    <span class="comment">//内部类使用枚举</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">enum</span> <span class="title class_">SingletonEnum</span> &#123;</span><br><span class="line">        <span class="variable constant_">INSTANCE</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">private</span> <span class="title class_">SingletonObj</span> singletonObj;</span><br><span class="line">            <span class="comment">//在枚举类的构造器里初始化singletonObj</span></span><br><span class="line">        <span class="title class_">SingletonEnum</span>() &#123;</span><br><span class="line">            singletonObj = <span class="keyword">new</span> <span class="title class_">SingletonObj</span>();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">private</span> <span class="title class_">SingletonObj</span> <span class="title function_">getSingletonObj</span>(<span class="params"></span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> singletonObj;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//对外部提供的获取单例的方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="title class_">SingletonObj</span> <span class="title function_">getInstance</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="comment">//获取单例对象，返回</span></span><br><span class="line">        <span class="keyword">return</span> <span class="title class_">SingletonEnum</span>.<span class="property">INSTANCE</span>.<span class="title function_">getSingletonObj</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//测试</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="built_in">void</span> <span class="title function_">main</span>(<span class="params"><span class="built_in">String</span>[] args</span>) &#123;</span><br><span class="line">        <span class="title class_">SingletonObj</span> a = <span class="title class_">SingletonObj</span>.<span class="title function_">getInstance</span>();</span><br><span class="line">        <span class="title class_">SingletonObj</span> b = <span class="title class_">SingletonObj</span>.<span class="title function_">getInstance</span>();</span><br><span class="line">        <span class="title class_">System</span>.<span class="property">out</span>.<span class="title function_">println</span>(a == b);<span class="comment">//true</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="left-join和inner-join的区别"><a href="#left-join和inner-join的区别" class="headerlink" title="left join和inner join的区别"></a>left join和inner join的区别</h2><p>画个图吧。</p>
<h2 id="一个url到后端的处理经过的过程"><a href="#一个url到后端的处理经过的过程" class="headerlink" title="一个url到后端的处理经过的过程"></a>一个url到后端的处理经过的过程</h2><p><img   class="lazyload" data-original="/java%E5%9F%BA%E7%A1%80%E9%81%97%E5%BF%98%E9%A2%98%E7%9B%AE/image-20230704175436169.png" src=""  alt="image-20230704175436169"></p>
<h2 id="自动拆箱空指针问题"><a href="#自动拆箱空指针问题" class="headerlink" title="自动拆箱空指针问题"></a>自动拆箱空指针问题</h2><p>这是自动装箱&#x2F;拆箱的特性，只要一个运算中有不同的类型，涉及到类型转换，那么编译器会往下（基本类型）转型，再进行运算。<br>就是说，如果运算中有int和Integer，Integer会先转成int再计算。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="type">boolean</span> <span class="variable">b</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line"><span class="type">Integer</span> <span class="variable">num</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="keyword">if</span>(num != <span class="literal">null</span>)&#123;</span><br><span class="line">    <span class="type">Integer</span> <span class="variable">result</span> <span class="operator">=</span> b ? <span class="number">0</span> : num;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="对泛型的理解"><a href="#对泛型的理解" class="headerlink" title="对泛型的理解"></a>对泛型的理解</h2><blockquote>
<p>借鉴：<a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/381859667">一文带你搞懂 Java 泛型 - 知乎 (zhihu.com)</a></p>
</blockquote>
<ul>
<li><p>作用</p>
<p>编译期类型安全</p>
<p>避免了强制类型转换运行时异常</p>
<p>同一个类可以操作多种类型数据，代码复用</p>
</li>
<li><p>开发场景</p>
<blockquote>
<p>统计结果返回ResultVo ,类型转换（把一个类型 E 的 List 转换为另一个类型 T 的 List）</p>
</blockquote>
<ul>
<li><p>统一接口返回</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ResultHelper</span>&lt;T&gt; <span class="keyword">implements</span> <span class="title class_">Serializable</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> T data;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">boolean</span> success;</span><br><span class="line">    <span class="keyword">private</span> Integer code;</span><br><span class="line">    <span class="keyword">private</span> String message;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">ResultHelper</span><span class="params">()</span> &#123;&#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; ResultHelper&lt;T&gt; <span class="title function_">wrapSuccessfulResult</span><span class="params">(T data)</span> &#123;</span><br><span class="line">        ResultHelper&lt;T&gt; result = <span class="keyword">new</span> <span class="title class_">ResultHelper</span>&lt;T&gt;();</span><br><span class="line">        result.data = data;</span><br><span class="line">        result.success = <span class="literal">true</span>;</span><br><span class="line">        result.code = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
<li><p>类型转换</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">    </span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> &lt;E, T&gt; List&lt;T&gt; <span class="title function_">convertListToList</span><span class="params">(List&lt;E&gt; input, Class&lt;T&gt; clzz)</span> &#123;</span><br><span class="line">    List&lt;T&gt; output = Lists.newArrayList();</span><br><span class="line">    <span class="keyword">if</span> (CollectionUtils.isNotEmpty(input)) &#123;</span><br><span class="line">        input.forEach(source -&gt; &#123;</span><br><span class="line">            <span class="type">T</span> <span class="variable">target</span> <span class="operator">=</span> BeanUtils.instantiate(clzz);</span><br><span class="line">            BeanUtils.copyProperties(source, target);</span><br><span class="line">            output.add(target);</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> output;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>字符串和Integer常考题目</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="type">Integer</span> <span class="variable">i</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">100</span>);</span><br><span class="line"><span class="type">Integer</span> <span class="variable">j</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">100</span>);</span><br><span class="line">(i == j) ? <span class="literal">false</span>  <span class="comment">// 只有valueOf才会使用常量池（-128~127），new Integer会直接创建新对象</span></span><br><span class="line"></span><br><span class="line"><span class="type">String</span> <span class="variable">a</span> <span class="operator">=</span> <span class="string">&quot;abc&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">b</span> <span class="operator">=</span> <span class="string">&quot;a&quot;</span> + <span class="string">&quot;b&quot;</span> + <span class="string">&quot;c&quot;</span>;  <span class="comment">// 经过编译器优化成了String str = “abc”</span></span><br><span class="line">(a == b) ? <span class="literal">true</span>  <span class="comment">// 字符串常量池，字面量相同的引用也相同</span></span><br><span class="line"></span><br><span class="line"><span class="type">String</span> <span class="variable">c</span> <span class="operator">=</span> <span class="string">&quot;abcd&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">d</span> <span class="operator">=</span> a + <span class="string">&quot;d&quot;</span>;  <span class="comment">// 经过编译器优化成了StringBuilder</span></span><br><span class="line">(c == d) ? <span class="literal">false</span></span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ul>

      </section>
      <section class="extra">
        
          <ul class="copyright">
  
    <li><strong>本文作者：</strong>东子</li>
    <li><strong>本文链接：</strong><a href="https://comebackearly.gitee.io/2022/06/04/java%E5%9F%BA%E7%A1%80%E9%81%97%E5%BF%98%E9%A2%98%E7%9B%AE/index.html" title="https:&#x2F;&#x2F;comebackearly.gitee.io&#x2F;2022&#x2F;06&#x2F;04&#x2F;java%E5%9F%BA%E7%A1%80%E9%81%97%E5%BF%98%E9%A2%98%E7%9B%AE&#x2F;index.html">https:&#x2F;&#x2F;comebackearly.gitee.io&#x2F;2022&#x2F;06&#x2F;04&#x2F;java%E5%9F%BA%E7%A1%80%E9%81%97%E5%BF%98%E9%A2%98%E7%9B%AE&#x2F;index.html</a></li>
    <li><strong>版权声明：</strong>本博客所有文章均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" title="BY-NC-SA" target="_blank" rel="noopener">BY-NC-SA</a> 许可协议，转载请注明出处！</li>
  
</ul>
        
        
        
        
  <nav class="nav">
    <a href="/2023/01/10/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"><i class="iconfont iconleft"></i>设计模式</a>
    <a href="/2022/06/04/redis/">redis<i class="iconfont iconright"></i></a>
  </nav>

      </section>
      
        <section class="comments">
  
    <div class="btn" id="comments-btn">查看评论</div>
  
  
<div id="valine"></div>
<script defer src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script>
  window.onload = function () {
    var loadValine = function () {
      new Valine({
        el: '#valine',
        app_id: "833C0IwLe9o8QE1pN25Mv59F-gzGzoHsz",
        app_key: "YLQZdn7egrZOmJnwr6YFEw0y",
        placeholder: "雁过留痕",
        avatar: "mp",
        pageSize: "10",
        lang: "zh-CN",
      });
    }
    if ( true ) {
      $("#comments-btn").on("click", function () {
        $(this).hide();
        loadValine();
      });
    } else {
      loadValine();
    }
  };
</script>

</section>
      
    </section>
  </div>
</article></div>
      <div class="col-xl-3">
        
          
  <aside class="toc-wrap">
    <h3 class="toc-title">文章目录：</h3>
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#java-%E9%81%97%E5%BF%98%E9%A2%98%E7%9B%AE"><span class="toc-text">java 遗忘题目</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%AF%B4-Java-%E8%AF%AD%E8%A8%80%E2%80%9C%E7%BC%96%E8%AF%91%E4%B8%8E%E8%A7%A3%E9%87%8A%E5%B9%B6%E5%AD%98%E2%80%9D%EF%BC%9F"><span class="toc-text">为什么说 Java 语言“编译与解释并存”？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%8C%85%E8%A3%85%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">基本类型和包装类型的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8C%85%E8%A3%85%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6%E4%BA%86%E8%A7%A3%E4%B9%88"><span class="toc-text">包装类型的缓存机制了解么</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B5%AE%E7%82%B9%E6%95%B0%E8%BF%90%E7%AE%97%E7%9A%84%E6%97%B6%E5%80%99%E4%BC%9A%E6%9C%89%E7%B2%BE%E5%BA%A6%E4%B8%A2%E5%A4%B1%E7%9A%84%E9%A3%8E%E9%99%A9%EF%BC%8C%E6%80%8E%E4%B9%88%E8%A7%A3%E5%86%B3%EF%BC%9F"><span class="toc-text">为什么浮点数运算的时候会有精度丢失的风险，怎么解决？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E4%B8%89%E5%A4%A7%E7%89%B9%E5%BE%81"><span class="toc-text">面向对象三大特征</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8E%A5%E5%8F%A3%E5%92%8C%E6%8A%BD%E8%B1%A1%E7%B1%BB%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB"><span class="toc-text">接口和抽象类有什么区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B7%B1%E6%8B%B7%E8%B4%9D%E5%92%8C%E6%B5%85%E6%8B%B7%E8%B4%9D%E5%8C%BA%E5%88%AB%E4%BA%86%E8%A7%A3%E5%90%97%EF%BC%9F%E4%BB%80%E4%B9%88%E6%98%AF%E5%BC%95%E7%94%A8%E6%8B%B7%E8%B4%9D%EF%BC%9F"><span class="toc-text">深拷贝和浅拷贝区别了解吗？什么是引用拷贝？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Object%E7%B1%BB%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-text">Object类的方法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#String%E3%80%81StringBuffer%E3%80%81StringBuilder-%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-text">String、StringBuffer、StringBuilder 的区别？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#java%E5%BC%82%E5%B8%B8%E7%B1%BB"><span class="toc-text">java异常类</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Throwable-%E7%B1%BB%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-text">Throwable 类常用方法有哪些</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#try%E3%80%81catch%E3%80%81finally-%E8%80%83%E5%AF%9F3%EF%BC%8C%E8%AF%B7%E6%8C%87%E5%87%BA%E4%B8%8B%E9%9D%A2%E7%A8%8B%E5%BA%8F%E7%9A%84%E8%BF%90%E8%A1%8C%E7%BB%93%E6%9E%9C"><span class="toc-text">try、catch、finally 考察3，请指出下面程序的运行结果</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E6%B3%9B%E5%9E%8B%EF%BC%9F%E6%9C%89%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8"><span class="toc-text">什么是泛型？有什么作用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%8D%E5%B0%84"><span class="toc-text">反射</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%B3%A8%E8%A7%A3"><span class="toc-text">注解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#SPI"><span class="toc-text">SPI</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BA%8F%E5%88%97%E5%8C%96%E5%92%8C%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96"><span class="toc-text">序列化和反序列化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B8%B8%E8%A7%81%E5%BA%8F%E5%88%97%E5%8C%96%E5%8D%8F%E8%AE%AE%E6%9C%89%E5%93%AA%E4%BA%9B-%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E6%8E%A8%E8%8D%90%E4%BD%BF%E7%94%A8jdk%E8%87%AA%E5%B8%A6%E7%9A%84%E5%8D%8F%E8%AE%AE"><span class="toc-text">常见序列化协议有哪些,为什么不推荐使用jdk自带的协议</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#String-s-x3D-new-String-%E2%80%9Cxyz%E2%80%9D-%E5%88%9B%E5%BB%BA%E4%BA%86%E5%87%A0%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AF%B9%E8%B1%A1%EF%BC%9F"><span class="toc-text">String s &#x3D; new String(“xyz”) 创建了几个字符串对象？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Java-%E9%9D%99%E6%80%81%E5%8F%98%E9%87%8F%E5%92%8C%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E7%9A%84%E5%8C%BA%E5%88%AB%E3%80%82"><span class="toc-text">Java 静态变量和成员变量的区别。</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#JDK1-8%E4%B9%8B%E5%90%8E%E6%9C%89%E5%93%AA%E4%BA%9B%E6%96%B0%E7%89%B9%E6%80%A7"><span class="toc-text">JDK1.8之后有哪些新特性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9B%B6%E7%A2%8E%E7%BB%86%E5%B0%8F"><span class="toc-text">零碎细小</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Math-round-11-5-%E7%AD%89%E4%BA%8E%E5%A4%9A%E5%B0%91%EF%BC%9F"><span class="toc-text">Math.round(11.5)等于多少？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#java%E4%B8%AD%E5%AD%982%E7%9A%8464-2%E7%9A%8464%E7%94%A8%E4%BB%80%E4%B9%88%E5%AD%98%EF%BC%9F"><span class="toc-text">java中存2的64*2的64用什么存？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#java%E6%97%A5%E6%9C%9F%E5%81%9A%E5%8A%A0%E5%87%8F%E6%B3%95"><span class="toc-text">java日期做加减法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#JUC"><span class="toc-text">JUC</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#wait-%E5%92%8C-sleep-%E6%96%B9%E6%B3%95%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">wait() 和 sleep() 方法的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E7%9A%84-sleep-%E6%96%B9%E6%B3%95%E5%92%8C-yield-%E6%96%B9%E6%B3%95%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-text">线程的 sleep() 方法和 yield() 方法有什么区别？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HashMap-%E7%9A%84%E9%BB%98%E8%AE%A4%E5%88%9D%E5%A7%8B%E5%AE%B9%E9%87%8F%E6%98%AF%E5%A4%9A%E5%B0%91%EF%BC%9FHashMap-%E7%9A%84%E5%AE%B9%E9%87%8F%E6%9C%89%E4%BB%80%E4%B9%88%E9%99%90%E5%88%B6%E5%90%97%EF%BC%9F"><span class="toc-text">HashMap 的默认初始容量是多少？HashMap 的容量有什么限制吗？</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HashMap-%E5%92%8CHashtable-%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">HashMap 和Hashtable 的区别?</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Java-%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84"><span class="toc-text">Java 内存结构</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB%E5%8A%A0%E8%BD%BD%E7%9A%84%E8%BF%87%E7%A8%8B"><span class="toc-text">类加载的过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E7%9A%84-join-%E6%96%B9%E6%B3%95%E6%98%AF%E5%B9%B2%E5%95%A5%E7%94%A8%E7%9A%84"><span class="toc-text">线程的 join() 方法是干啥用的</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%96%E5%86%99%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E6%9C%89%E5%87%A0%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F"><span class="toc-text">编写多线程程序有几种实现方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Thread-%E8%B0%83%E7%94%A8-start-%E6%96%B9%E6%B3%95%E5%92%8C%E8%B0%83%E7%94%A8-run-%E6%96%B9%E6%B3%95%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">Thread 调用 start() 方法和调用 run() 方法的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Java%E4%B8%AD%E7%BA%BF%E7%A8%8B%E5%87%A0%E7%A7%8D%E7%8A%B6%E6%80%81"><span class="toc-text">Java中线程几种状态</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#synchronized-%E5%92%8C-Lock-%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">synchronized 和 Lock 的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E6%B1%A0%E7%9A%84%E5%8F%82%E6%95%B0"><span class="toc-text">线程池的参数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BA%BF%E7%A8%8B%E6%B1%A0%E6%9C%89%E5%93%AA%E4%BA%9B%E6%8B%92%E7%BB%9D%E7%AD%96%E7%95%A5"><span class="toc-text">线程池有哪些拒绝策略</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88String%E5%AE%9A%E4%B9%89%E4%B8%BAfinal"><span class="toc-text">为什么String定义为final</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#HashMap%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E6%96%B9%E6%B3%95%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-text">HashMap中常用的方法有哪些</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%9A%E4%B8%BE%EF%BC%8C%E4%BB%A5%E5%8F%8A%E6%9E%9A%E4%B8%BE%E7%9A%84%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86"><span class="toc-text">枚举，以及枚举的底层原理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C"><span class="toc-text">基本操作</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E7%90%86"><span class="toc-text">原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9E%9A%E4%B8%BE%E5%AE%9E%E7%8E%B0%E5%8D%95%E4%BE%8B"><span class="toc-text">枚举实现单例</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#left-join%E5%92%8Cinner-join%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">left join和inner join的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%80%E4%B8%AAurl%E5%88%B0%E5%90%8E%E7%AB%AF%E7%9A%84%E5%A4%84%E7%90%86%E7%BB%8F%E8%BF%87%E7%9A%84%E8%BF%87%E7%A8%8B"><span class="toc-text">一个url到后端的处理经过的过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E6%8B%86%E7%AE%B1%E7%A9%BA%E6%8C%87%E9%92%88%E9%97%AE%E9%A2%98"><span class="toc-text">自动拆箱空指针问题</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9%E6%B3%9B%E5%9E%8B%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-text">对泛型的理解</span></a></li></ol></li></ol>
  </aside>

        
      </div>
    </div>
  </div>
</main>
  

<footer class="footer">
  <div class="footer-social"><a 
        href="tencent://message/?Menu=yes&uin=2911890696 "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#12B7F5'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  iconQQ "></i>
      </a><a 
        href="javascript:; "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#09BB07'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  iconwechat-fill "></i>
      </a><a 
        href="https://github.com/nuban "
        target="_blank"
        class="footer-social-item"
        onMouseOver="this.style.color= '#9f7be1'" 
        onMouseOut="this.style.color='#33333D'">
          <i class="iconfont  icongithub-fill "></i>
      </a></div>
  
    <div class="footer-copyright"><p>Powered by <a target="_blank" href="https://gitee.com/comebackearly">东子</a>  | 爷-青结~~</p></div>
  
  <link rel="stylesheet" href="/dist/APlayer.min.css">
  <div id="aplayer"></div>
  <script type="text/javascript" src="/dist/APlayer.min.js"></script>
  <script type="text/javascript" src="/dist/music.js"></script>
  
</footer>
  
      <div class="fab fab-plus">
    <i class="iconfont iconplus"></i>
  </div>
  
  
  
  <div class="fab fab-up">
    <i class="iconfont iconcaret-up"></i>
  </div>
  
  
  
    
<script src="/js/color-mode.js"></script>

  
  
</body>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>





  
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script>




  
<script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js"></script>






  
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>




<script src="/js/utils.js"></script>
<script src="/js/script.js"></script>







  <script>
    (function () {
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
      } else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
      }
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
    })();
  </script>



  <script defer src='https://hm.baidu.com/hm.js?dda12e485d1b1d3113db8147f482111c'></script>











</html>